package pro.cherish.http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.util.AsciiString;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.CharEncoding;
import org.apache.commons.io.Charsets;
import pro.cherish.http.pojo.User;
import pro.cherish.http.serialize.impl.JSONSerializer;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author 创建人：lys
 * @version 版本号：V1.0
 * <p>
 * ***************************修订记录************************************
 * 2020-6-15 lys 创建该类功能。
 * **********************************************************************
 * </p>
 * @ClassName 类名：HttpHelloWorldServerHandler
 * @Description 功能说明：
 * <p>
 * TODO
 * </p>
 * **********************************************************************
 * @date 创建日期： 2020-6-15 
 */
@Slf4j
public class HttpHelloWorldServerHandler extends SimpleChannelInboundHandler<HttpObject> {
	private HttpHeaders headers;
	private HttpRequest httpRequest;
	private FullHttpRequest fullHttpRequest;
	private static final String FILE_UPLOAD = "/data/";

	private static final String FAVICON_ICO = "/favicon.ico";
	private static final AsciiString CONTENT_TYPE = AsciiString.cached("Content-Type");
	private static final AsciiString CONTENT_LENGTH = AsciiString.cached("Content-Length");
	private static final AsciiString CONNECTION = AsciiString.cached("Connection");
	private static final AsciiString KEEP_ALIVE = AsciiString.cached("keep-alive");

	private HttpPostRequestDecoder httpDecoder;

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
		User user = new User();
		user.setUserName("cherish");
		user.setDate(new Date());
		if (msg instanceof HttpRequest) {
			httpRequest = (HttpRequest) msg;
			headers = httpRequest.headers();
			String uri = httpRequest.uri();
			log.info("uri={}", uri);
			if (uri.equals(FAVICON_ICO)) {
				return;
			}
			HttpMethod method = httpRequest.method();
			if (method.equals(HttpMethod.GET)) {
				QueryStringDecoder queryDecoder = new QueryStringDecoder(uri, Charsets.toCharset(CharEncoding.UTF_8));
				Map<String, List<String>> uriAttributes = queryDecoder.parameters();
				//此处仅打印请求参数（你可以根据业务需求自定义处理）
				for (Map.Entry<String, List<String>> attr : uriAttributes.entrySet()) {
					for (String attrVal : attr.getValue()) {
						log.info(attr.getKey() + "=" + attrVal);
					}
				}
				user.setMethod("get");
			} else if (method.equals(HttpMethod.POST)) {
				//POST请求,由于你需要从消息体中获取数据,因此有必要把msg转换成FullHttpRequest
				fullHttpRequest = (FullHttpRequest) msg;
				//根据不同的Content_type处理body数据
				dealWithContentType(ctx, msg);
				user.setMethod("post");
			}
			JSONSerializer jsonSerializer = new JSONSerializer();
			byte[] content = jsonSerializer.serialize(user);
			FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(content));
			response.headers().set(CONTENT_TYPE, "text/plain");
			response.headers().set(CONTENT_LENGTH, response.content().readableBytes());
			boolean keepAlive = HttpUtil.isKeepAlive(httpRequest);
			if (!keepAlive) {
				ctx.write(response).addListener(ChannelFutureListener.CLOSE);
			} else {
				response.headers().set(CONNECTION, KEEP_ALIVE);
				ctx.write(response);
			}
			ctx.flush();
		}
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		cause.printStackTrace();
		ctx.close();
	}

	private void dealWithContentType(ChannelHandlerContext ctx, HttpObject httpObject) throws IOException {
		String contentType = getContentType();
		//可以使用HttpJsonDecoder
		if (contentType.equals("application/json")) {
			String jsonStr = fullHttpRequest.content().toString(Charsets.toCharset(CharEncoding.UTF_8));
			JSONObject obj = JSON.parseObject(jsonStr);
			for (Map.Entry<String, Object> item : obj.entrySet()) {
				log.info(item.getKey() + "=" + item.getValue().toString());
			}
		} else if (contentType.equals("application/x-www-form-urlencoded")) {
			String jsonStr = fullHttpRequest.content().toString(org.apache.commons.codec.Charsets.toCharset(CharEncoding.UTF_8));
			QueryStringDecoder queryDecoder = new QueryStringDecoder(jsonStr, false);
			Map<String, List<String>> uriAttributes = queryDecoder.parameters();
			for (Map.Entry<String, List<String>> attr : uriAttributes.entrySet()) {
				for (String attrVal : attr.getValue()) {
					log.info(attr.getKey() + "=" + attrVal);
				}
			}
		} else if (contentType.equals("multipart/form-data")) {
			//TODO 用于文件上传

		} else {
			//do nothing...
		}
	}


	private String getContentType() {
		String typeStr = headers.get("Content-Type");
		String[] split = typeStr.split(";");
		return split[0];

	}
}
